package cc.owoo.godpen.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * 绑定值设置
 * Created by nimensei
 * 2022-06-04 上午 12:29
 */
public record KeyBindSet(Field field, ValueSet valueSet) implements ValueSet {
    @Override
    public boolean set(Object object, Object value) throws IllegalAccessException, InvocationTargetException {
        return bind(object, data -> valueSet.set(data, value));
    }

    @Override
    public boolean fill(Object object, Object value) throws IllegalAccessException, InvocationTargetException {
        return bind(object, data -> valueSet.fill(data, value));
    }

    /**
     * 绑定值
     *
     * @param object 需要被设置值的对象
     * @param onBind 绑定值回调函数
     * @return 是否设置成功
     * @throws IllegalAccessException    设置值时发生了异常，需要检查传入的对象是否具有这个字段，或是值是否能够被转换
     * @throws InvocationTargetException 函数通过反射调用时发生了异常，请检查传入的对象是否具有这个函数，或是函数的值是否能够被转换
     */
    private boolean bind(Object object, OnBind onBind) throws IllegalAccessException, InvocationTargetException {
        Object data = field.get(object);
        boolean isSet = data == null;
        if (isSet)
            try {
                data = field.getType().getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                return false;
            }
        onBind.bind(data);
        if (isSet)
            field.set(object, data);
        return true;
    }

    /**
     * 设置绑定的值
     */
    private interface OnBind {
        /**
         * 设置绑定的值
         *
         * @param data 绑定对象
         */
        void bind(Object data) throws IllegalAccessException, InvocationTargetException;
    }
}
